//
// Created by TheHun on 2021/6/17.
//

#include "rawData.h"

// new csv data struct
RawData* NewCsvData(int rowSize, int colSize) {
    return NewRawData(',', rowSize, colSize);
}

// new data struct
RawData* NewRawData(char separator, int rowSize, int colSize) {
    if (rowSize <= 0 || colSize <= 0) {
        printf("Illegal rowSize or colSize!");
        return NULL;
    }
    RawData* rawData = (RawData*)malloc(sizeof(RawData));
    rawData->separator = separator;
    rawData->rowSize = rowSize;
    rawData->colSize = colSize;
    rawData->data = (double**)malloc(sizeof(double*) * rowSize);
    for (int i = 0; i < rowSize; i++) {
        rawData->data[i] = (double*)malloc(sizeof(double) * colSize);
    }
    return rawData;
}

// get total rows count of a file
int GetTotalRowCount(FILE * fp) {
    int i = 0;
    char strLine[MAX_LINE_SIZE];
    fseek(fp, 0, SEEK_SET);
    while (fgets(strLine, MAX_LINE_SIZE, fp)) {
        i++;
    }
    fseek(fp, 0, SEEK_SET);
    return i;
}

// get total columns count of a file
int GetTotalColCount(FILE * fp, char separator) {
    int i = 0, sepCount = 0;
    char strLine[MAX_LINE_SIZE];
    fseek(fp, 0, SEEK_SET);
    if (fgets(strLine, MAX_LINE_SIZE, fp)) {
        while (i < MAX_LINE_SIZE && strLine[i] != 0) {
            if (strLine[i] == separator) {
                sepCount++;
            }
            i++;
        }
        i = sepCount + 1;
    } else {
        fseek(fp, 0, SEEK_SET);
        return -1;
    }
    fseek(fp, 0, SEEK_SET);
    return i;
}

// read data from file
void loadDataFromFile(RawData* target, FILE* fp) {
    if (fp == NULL) {
        printf("File pointer is NULL!\n");
        return;
    }
    char* sep = (char*)malloc(sizeof(char) * 2);
    sep[0] = target->separator;
    sep[1] = '\0';

    int rowSize = target->rowSize;
    int colSize = target->colSize;
    if (rowSize <= 0 || colSize <= 0 || target->separator == 0) {
        printf("Uninitialized data struct!\n");
        return;
    }
    double** dataPtr = target->data;

    char buffer[MAX_LINE_SIZE];
    char* tmp = NULL;
    for (int i = 0; i < rowSize; i++) {
        int j = 0;
        if (fgets(buffer, MAX_LINE_SIZE, fp)) {
           tmp = strtok(buffer, sep);
           while (tmp != NULL) {
               if (i == 0) {
                   int z = 0;
                   while (tmp[z] != '\0' && !isDigitChar(tmp[z])) {
                       z++;
                   }
                   if (tmp[z] == '\0') {
                       continue;
                   } else {
                       tmp = &tmp[z]; // TODO may cause memory problem
                   }
               }
               dataPtr[i][j] = atof(tmp);
               j++;
               tmp = strtok(NULL, sep);
           }
        }
    }
}

int isDigitChar(char digit) {
    if (digit == '+' || digit == '-' || digit == '.') {
        return 1;
    }
    if (digit <= '9' && digit >= '0') {
        return 1;
    }
    return 0;
}
